#pragma once 

#include "Thread.hpp"
#include "LockGuard.hpp"
#include <vector>
#include <queue>
#include <unistd.h>

const int g_thread_num = 5;
const int g_queue_capacity = 5;

template<class T>
class ThreadPool
{
private:
    bool IsFull()
    {
        return _block_queue.size() == _queue_capacity;
    }

    bool IsEmpty()
    {
        return _block_queue.size() == 0;
    }

public:
    ThreadPool(int thread_num = g_thread_num, int queue_capacity = g_queue_capacity)
        : _thread_num(thread_num), _queue_capacity(queue_capacity)
    {
        pthread_mutex_init(&_mtx, nullptr);
        pthread_cond_init(&_cond_full, nullptr);
        pthread_cond_init(&_cond_empty, nullptr);

        for(int i = 0; i < _thread_num; ++i)
        {
            std::string name = "Thread ";
            name += std::to_string(i + 1);
            _thread.push_back(new Thread(name, ThreadRoutine, (void*)this));
        }
    }

    // 线程池启动函数
    void run()
    {
        for(int i = 0; i < _thread_num; ++i)
        {
            _thread[i]->start();
        }
    }

    // 插入任务函数
    void push_task(T task)
    {
        logMessage(NORMAL, "PUSH TASK!\n");
        {
            LockGuard LockGuard(_mtx);
            while(IsFull()) 
            {
                logMessage(NORMAL, "WAIT ISFULL!\n");
                // std::cout << "size: " << _block_queue.size() << std::endl;
                pthread_cond_wait(&_cond_full, &_mtx);
            }

            _block_queue.push(task);
            pthread_cond_signal(&_cond_empty);
        }

        logMessage(NORMAL, "PUSH END!\n");
    }

    ~ThreadPool()
    {
        pthread_mutex_destroy(&_mtx);
        pthread_cond_destroy(&_cond_full);
        pthread_cond_destroy(&_cond_empty);

        for(int i = 0; i < _thread_num; ++i)
        {
            delete _thread[i];
        }
    }

private:
    // 线程函数（处理任务）
    static void* ThreadRoutine(void *args)
    {
        ThreadData *ptr_data = (ThreadData *)args;
        ThreadPool *ptr_pool = (ThreadPool *)ptr_data->_args;

        while(true)
        {
            T task;
            {
                LockGuard lockguard(ptr_pool->_mtx);
                while(ptr_pool->IsEmpty())
                {
                    pthread_cond_wait(&ptr_pool->_cond_empty, &ptr_pool->_mtx);
                }

                // std::cout << ptr_data->_name << "# " << std::flush;
                task = ptr_pool->_block_queue.front();
                ptr_pool->_block_queue.pop();

                pthread_cond_signal(&ptr_pool->_cond_full);
                // usleep(rand() % 500);
            }

            task();
        }
        
        // while(true)
        // {
        //     std::cout << ptr_data->_name << std::endl;
        //     sleep(1);
        // }

        return nullptr;
    }

    std::vector<Thread *> _thread;  
    std::queue<T> _block_queue;
    int _queue_capacity;  // 队列最大容量
    int _thread_num;      // 线程数量
    pthread_mutex_t _mtx;           // 互斥锁
    pthread_cond_t _cond_full;   // 表示任务队列是否已满的信号量
    pthread_cond_t _cond_empty;  // 表示任务队列是否为空的信号量    
};